module System.BootInfo;
private import std.string;
private import System.Console;
//private import Explode.GameConfig;
private import std.file;
//private import std.c.stdlib;

public class BootInfo{
	private string[] args;
	public string execDir = ".";
	private int _screenWidth = -1 , _screenHeight = -1;
	private bool _fullscreen = false , _screensaver = false , _muted = false;
	private string _configFile = "config.ini";
	private string _stageFile  = "_data/stage/stage0.txt";
	private string _mapchip    = "_data/img/mapchip.bmp";
	public int screenWidth(){
		return _screenWidth;
	} //
	public int screenHeight(){
		return _screenHeight;
	} //
	public bool isFullscreen(){
		return _fullscreen;
	} //
	public bool isScreensaver() {
		return _screensaver;
	} //
	public bool isMuted() {
		return _muted;
	} //
	public string configFile(){
		return _configFile;
	} //
	public string stageFile(){
		return _stageFile;
	} //

	public int frameSkip(){
		return 0;
	} //
	
	public string mapchip(){
		return _mapchip;
	} //
	
	
	public this(string[] args){
		this.args = args;
			version(Mac_release) {
				string[] tmp = split( args[0] , "/")[0..length-1];
				Console.writeln("currentdir=%s" , getcwd() );
				execDir = join(tmp , "/" );
			}
		foreach( int t , string buf ; args ) {
			switch ( buf ) {
				case "-m":
					_muted       = true;
					break;
				case "/S":
				case "/s":
					_screensaver = true;
					_muted       = true;
					// スクリーンセーバー時にカレントディレクトリを自身のパスへ移動する
					version(Win32) {
						string[] tmp = split( args[0] , "\\")[0..length-1];
						execDir = join(tmp , "\\" );
						chdir( execDir );
					}
				case "-f":
					_fullscreen = true;
					break;
				case "-w":
					_fullscreen = false;
					break;
				case "-r":
					_screenWidth  = cast(int)std.string.atoi(args[ ++t ]);
					_screenHeight = cast(int)std.string.atoi(args[ ++t ]);
					break;
				case "-c":
					_configFile = args[ ++t ] ;
					break;
				case "-stage":
					_stageFile = args[ ++t ] ;
					break;
				case "-mapchip":
					_mapchip = args[ ++t ] ;
					break;
				default:
//					Console.writeln("unknown parameter [%s]" , buf);
					break;
			}
		} //
		SystemConfig.load( this , _configFile );
		initData();
	} //
	
	private void initData(){
		alias SystemConfig s;
		if ( _screenWidth  < 0 ) _screenWidth  = s.getParam( "SCREENWIDTH"  , 800 );
		if ( _screenHeight < 0 ) _screenHeight = s.getParam( "SCREENHEIGHT" , 600 );
		if ( _screensaver ) {
			_screenWidth  = s.getParam( "SCREENSAVERWIDTH"  , _screenWidth );
			_screenHeight = s.getParam( "SCREENSAVERHEIGHT" , _screenHeight );
		}
		s.setParam( "PLAYCNT" , s.getParam( "PLAYCNT" , 0 ) + 1 );
		if ( _screensaver ) {
			s.setParam( "SCREENSAVER"  , 1  );
			if ( s.getParam( "SCREENSAVERSOUND"  , 0  ) == 1 ) _muted = false;
		}
		 else				s.setParam( "SCREENSAVER"  , 0  );
	} //
	
	public ~this(){
		alias SystemConfig s;
		if ( !_screensaver ) {
			s.setParam( "SCREENWIDTH"  , _screenWidth  );
			s.setParam( "SCREENHEIGHT" , _screenHeight );
		}
		SystemConfig.save( _configFile );
	} //
} //

public static final class SystemConfig {
	private static string[ string ] _data;
	private static string _fileName ;

	private static bool fileCopy( string src , string to ) {
		 try{
			if ( exists( to ) ) return true;
			if ( !exists( src ) ) return false;
			if ( !isfile( src ) ) return false;
			if ( isdir(   src ) ) return false;
			Console.writeln("\t%s" , src , to);
			std.file.copy( src , to );
			return true;
		} catch ( FileException fe ) {
			return false;
		}
	} //
	private static bool dirCopy( string src , string to ) {
		Console.writeln("dircopy %s -> %s" , src , to);
		string[] files = listdir( src );
		foreach ( string file ; files ) {
			fileCopy( src ~ file , to ~ file );
		}
		return true;
	} //

	private static void initDir( BootInfo info ) {
		version( Win32 ) { 
			return ;
		} else {
			char* hm = std.c.stdlib.getenv("HOME");
			string homeDir = std.string.toString( hm);//std.c.stdlib.getenv("HOME");//getcwd();
			string execDir = info.execDir;
			chdir( homeDir );

			if ( !exists("Library") ) mkdir( "Library" );
			chdir("Library");
			if ( !exists("ExplodeRunner") ) mkdir( "ExplodeRunner" );
			chdir("ExplodeRunner");

			if ( !exists("_data") ) mkdir( "_data" );
			if ( !exists("_data/img") ) mkdir( "_data/img" );
			if ( !exists("_data/stage") ) mkdir( "_data/stage" );
			if ( !exists("_data/stage/replay") ) mkdir( "_data/stage/replay" );
			if ( !exists("_data/sound") ) mkdir( "_data/sound" );

			if ( !exists("resource") ) mkdir( "resource" );
			if ( !exists("resource/font") ) mkdir( "resource/font" );
			

			dirCopy( execDir ~ "/_data/img/"		  , "_data/img/");
			dirCopy( execDir ~ "/_data/stage/"		  , "_data/stage/");
			dirCopy( execDir ~ "/_data/stage/replay/" , "_data/stage/replay/");
			dirCopy( execDir ~ "/_data/sound/"		  , "_data/sound/");
			
			dirCopy( execDir ~ "/resource/"			  , "resource/");
			dirCopy( execDir ~ "/resource/font/"	  , "resource/font/");
			

		}
	} //


	public static void load( BootInfo info , string fileName = "config.ini") {
		 try{
			initDir( info );
			_fileName = fileName;

			string[string] dat;
			_data = dat;

			if ( !exists( fileName ) )return;
			string buf = cast(string)read( _fileName );
			string[] lines = split( buf , "\n" );
			foreach (int t , string ln ; lines ) {
				ln = strip( ln );
				if ( ln.length < 1 ) continue;
				int eq = find( ln , "=" );//.indexOf("=");
				
				if ( eq > 1 ) {
					string[] v = split( ln , "=" );
					string name = ( strip( v[0] ) ), val = strip( v[1] );
					Console.writeln("SystemConfig.load: '%s'='%s'" , name , val );
					_data[ name ] = val;
				}
			}
		 } catch ( Object e ) {
		 	Console.writeln("FileException:%s" , e.toString() );
		 }
	} //

	public static void save( string fileName = "config.ini" ) {
		 try{
			string tmpfile = fileName ~ ".tmp";
			string bkfile = fileName ~ ".bk";
			if ( exists( tmpfile ) ) remove( tmpfile );
			foreach(  string name,val ; _data ) {
//				Console.writeln("SystemConfig.save '%s'='%s'" , name , val );
				append( tmpfile , name ~"="~ val ~"\n");
			}
			if ( exists( bkfile ) ) remove( bkfile );
			if ( exists( fileName ) ) rename( fileName , bkfile );
			rename( tmpfile , fileName );
		 } catch ( Object e ) {
		 	Console.writeln("FileException:%s" , e.toString() );
		 }
	} //
/*	
	public static void setParam(T)( string name , T value ) {
		_data[ name ] = value.toString();
	} //
*/
	public static void setParam( string name , string value ) {
		_data[ name ] = value;
	} //
	public static void setParam( string name , int value ) {
		_data[ name ] = std.string.toString( value );
	} //
	public static void setParam( string name , float value ) {
		_data[ name ] = std.string.toString( value );
	} //
/*
	public static void setParamN(T)( string name , T value ) {
		_data[ name ] = std.string.toString( value );
	} //
*/
	public static string getParam( string name , string defValue ) {
		if ( name in _data ) return _data[ name ];
							 return defValue;
	} //
	public static int    getParam( string name , int defValue ) {
		if ( name in _data ) return cast(int)atoi( _data[ name ] );
		else				 return defValue;
	} //
	public static float  getParam( string name , float defValue ) {
		if ( name in _data ) return atof( _data[ name ] );
		else				 return defValue;
	} //

} //